/*****************************************************************************
 * file  : systask.c
 * creat : apleilx
 * data  : 2017/11/05
 *******************************************************************************/
#define _SYSTASK_MODULE_
#include "os_obj.h"
#include "sys_task.h"
#include "pincfg.h"
#include "common.h"
#include "swap.h"
#include "nor_cmd.h"
#include "nand_w25n.h"
#include "bsp_api.h"
#include "fun_list.h"
#include "mbedtls\aes.h"
#include "bsp_qpi_nor.h"
#include "symbol_def.h"

/*****************************************************************************
 * @brief   fun.
 *****************************************************************************/
void sys_led_ctr(void);
void sys_tick_exe(void);
void system_info(void);
FUN_LIST_REF(nsys);
FUN_LIST_REF(napp);

/*****************************************************************************
 * @brief   var.
 *****************************************************************************/

/*****************************************************************************
 * @brief   system task.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void task_system(const void *argument)
{
	uint32_t tick;

	sys_init();

	app_timer_task_add(sys_tick_exe);

	while (1)
	{

		fun_list_run_once(nsys);
		fun_list_run_once(napp);

		Gst.info.stack_used = stack_used();

		Gst.u_tick = app_tick_get();

		// 虚拟RTC
		pulse_creat(&Gst.pulse, Gst.u_tick);
		if (Gst.pulse.pulse_1s)
		{
			TimeRun(&Gst.rtc_time);
		}

		sys_app_run_once();

		tick = app_tick_get();
		// bsp_dly_ms(200);
		Gst.bsp_dly_verify = app_tick_get() - tick;

		NOP1();
		osDelay(ms_ticks(10));
		NOP1();
	}
}

/*****************************************************************************
 * @brief   led control.
 *****************************************************************************/
void sys_led_ctr(void)
{
	static word_tt st = {1};

	if (!Gst.pulse.pulse_10ms)
		return;

	// 位移
	if (Gst.pulse.pulse_10ms)
	{
		st.uval = bit16_roll_shift_left(st.uval, 4, 1);
	}

	// 输出
	o_led1.out(st.bits.b0);
	o_led2.out(st.bits.b1);
	o_led3.out(st.bits.b2);
}
obj_app_order(sys_led_ctr);

/*****************************************************************************
 * @brief   flash opt.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
int flash(int argc, char *argv[])
{
	uu8 *buff, er = 0, rd = 0, wr = 0;
	uu32 addr = 1 * 1024 * 1024, len = 128;

	// 操作方式
	if (argc >= 2)
	{
		char *str = argv[1];

		if (str[0] == 'e')
			er = 1;
		if (str[0] == 'r')
			rd = 1;
		if (str[0] == 'w')
			wr = 1;
	}
	else
	{
		er = 1;
		wr = 1;
		rd = 1;
	}

	// 操作地址
	if (argc >= 3)
	{
		addr = atoi(argv[2]) * 1024;
	}

	// 操作数量
	if (argc >= 4)
	{
		len = atoi(argv[3]);
	}

	// 操作
	buff = malloc(len + 20);

	if (er)
	{
		loop(256)
			bsp_snor_sector_erase(addr + index * 4096);
		dbg_print("erase flash : 0X%08X\n", addr);
	}

	if (wr)
	{
		loop(len)
			buff[index] = index;

		bsp_snor_write_multi(addr, len, buff);

		dbg_print("write flash : 0X%08X\n", addr);
	}

	if (rd)
	{
		loop(len)
			buff[index] = 0;

		bsp_snor_read(addr, len, buff);

		dbg_print("read flash : 0X%08X\n", addr);
		dbg_u8_print("NOR READ:\n", buff, len, 16);
	}

	free(buff);

	return 0;
}
SHELL_FUN_EXPORT(flash);

/*****************************************************************************
 *
 * @brief   task switch hook.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void task_sw_hook(char pos)
{
}

/*****************************************************************************
 *
 * @brief   sys_tick_exe
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void sys_tick_exe(void)
{
}

/*****************************************************************************
 * @brief   system info.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void system_info(void)
{
	crm_clocks_freq_type clocks;

	crm_clocks_freq_get(&clocks);

	dbg_puts(SYMBOL_LINE_EQ CR);

	dbg_puts(asc_pic_light);

	dbg_puts(SYMBOL_LINE_EQ CR);
	dbg_print("HCLK = %d MHZ, PCLK1 = %d MHZ, PCLK2 = %d MHZ\n",
			  clocks.ahb_freq / 1000000,
			  clocks.apb1_freq / 1000000,
			  clocks.apb2_freq / 1000000);
	dbg_puts(SYMBOL_LINE_EQ CR);
}

/*****************************************************************************
 * @brief   tick get.
 *
 * @ Pass/ Fail criteria: tick
 *****************************************************************************/
unsigned long rt_tick_get(void)
{
	return app_tick_get();
}

fun_list_hook(nsys)
{
}
